/*!
 * Dropdownhover v1.0.0 (http://bs-dropdownhover.kybarg.com)
 */
+ function($) {
    'use strict';

    // DROPDOWNHOVER CLASS DEFINITION
    // =========================

    var Dropdownhover = function(element, options) {
        this.options = options
        this.$element = $(element)

        var that = this

        // Defining if navigation tree or single dropdown
        this.dropdowns = this.$element.hasClass('nav-link') ? this.$element.parent().find('.dropdown-menu').parent('.dropdown') : this.$element.find('.dropdown')

        this.dropdowns.each(function() {
            $(this).on('mouseenter.bs.dropdownhover', function(e) {

                that.show($(this).children('a, button'))
            })
        })
        this.dropdowns.each(function() {
            $(this).on('mouseleave.bs.dropdownhover', function(e) {

                that.hide($(this).children('a, button'))
            })
        })

    }

    Dropdownhover.TRANSITION_DURATION = 300
    Dropdownhover.DELAY = 150
    Dropdownhover.TIMEOUT

    Dropdownhover.DEFAULTS = {
        animations: ['fadeInDown', 'fadeInRight', 'fadeInUp', 'fadeInLeft'],
    }

    // Opens dropdown menu when mouse is over the trigger element
    Dropdownhover.prototype.show = function(_dropdownLink) {


        var $this = $(_dropdownLink)

        window.clearTimeout(Dropdownhover.TIMEOUT)
        // Close all dropdowns
        $('.dropdown').not($this.parents()).each(function() {
            $(this).removeClass('show');
        });

        var effect = this.options.animations[0]

        if ($this.is('.disabled, :disabled')) return

        var $parent = $this.parent()
        var isActive = $parent.hasClass('show')

        if (!isActive) {

            var $dropdown = $this.next('.dropdown-menu')
            var relatedTarget = {
                relatedTarget: this
            }

            $parent
                .addClass('show')

            var side = this.position($dropdown)
            side == 'top' ? effect = this.options.animations[2] :
                side == 'right' ? effect = this.options.animations[3] :
                side == 'left' ? effect = this.options.animations[1] :
                effect = this.options.animations[0]

            $dropdown.addClass('animated ' + effect)

            var transition = $.support.transition && $dropdown.hasClass('animated')

            transition ?
                $dropdown
                .one('bsTransitionEnd', function() {
                    $dropdown.removeClass('animated ' + effect)
                })
                .emulateTransitionEnd(Dropdownhover.TRANSITION_DURATION) :
                $dropdown.removeClass('animated ' + effect)
        }

        return false
    }

    // Closes dropdown menu when mouse is out of it
    Dropdownhover.prototype.hide = function(_dropdownLink) {

        var that = this
        var $this = $(_dropdownLink)
        var $parent = $this.parent()
        Dropdownhover.TIMEOUT = window.setTimeout(function() {
            $parent.removeClass('show')
        }, Dropdownhover.DELAY)
    }

    // Calculating position of dropdown menu
    Dropdownhover.prototype.position = function(dropdown) {

        var win = $(window);

        // Reset css to prevent incorrect position
        dropdown.css({
            bottom: '',
            left: '',
            top: '',
            right: ''
        }).removeClass('dropdownhover-top')

        var viewport = {
            top: win.scrollTop(),
            left: win.scrollLeft()
        };
        viewport.right = viewport.left + win.width();
        viewport.bottom = viewport.top + win.height();

        var bounds = dropdown.offset();
        bounds.right = bounds.left + dropdown.outerWidth();
        bounds.bottom = bounds.top + dropdown.outerHeight();
        var position = dropdown.position();
        position.right = bounds.left + dropdown.outerWidth();
        position.bottom = bounds.top + dropdown.outerHeight();

        var side = ''

        var isSubnow = dropdown.parents('.dropdown-menu').length

        if (isSubnow) {

            if (position.left < 0) {
                side = 'left'
                dropdown.removeClass('dropdownhover-right').addClass('dropdownhover-left')
            } else {
                side = 'right'
                dropdown.addClass('dropdownhover-right').removeClass('dropdownhover-left')
            }

            if (bounds.left < viewport.left) {
                side = 'right'
                dropdown.css({
                    left: '100%',
                    right: 'auto'
                }).addClass('dropdownhover-right').removeClass('dropdownhover-left')
            } else if (bounds.right > viewport.right) {
                side = 'left'
                dropdown.css({
                    left: 'auto',
                    right: '100%'
                }).removeClass('dropdownhover-right').addClass('dropdownhover-left')
            }

            if (bounds.bottom > viewport.bottom) {
                dropdown.css({
                    bottom: 'auto',
                    top: -(bounds.bottom - viewport.bottom)
                })
            } else if (bounds.top < viewport.top) {
                dropdown.css({
                    bottom: -(viewport.top - bounds.top),
                    top: 'auto'
                })
            }

        } else { // Defines special position styles for root dropdown menu

            var parentLi = dropdown.parent('.dropdown')
            var pBounds = parentLi.offset()
            pBounds.right = pBounds.left + parentLi.outerWidth()
            pBounds.bottom = pBounds.top + parentLi.outerHeight()

            if (bounds.right > viewport.right) {
                dropdown.css({
                    left: -(bounds.right - viewport.right),
                    right: 'auto'
                })
            }

            if (bounds.bottom > viewport.bottom && (pBounds.top - viewport.top) > (viewport.bottom - pBounds.bottom) || dropdown.position().top < 0) {
                side = 'top'
                dropdown.css({
                    bottom: '100%',
                    top: 'auto'
                }).addClass('dropdownhover-top').removeClass('dropdownhover-bottom')
                dropdown.parent().addClass('dropdown-top').removeClass('dropdown-bottom')
            } else {
                side = 'bottom'
                dropdown.addClass('dropdownhover-bottom')
                dropdown.parent().addClass('dropdown-bottom').removeClass('dropdown-top')
            }
        }

        return side;

    }


    // DROPDOWNHOVER PLUGIN DEFINITION
    // ==========================

    function Plugin(option) {
        return this.each(function() {
            var $this = $(this)
            var data = $this.data('bs.dropdownhover')
            var settings = $this.data()
            if ($this.data('animations') !== undefined && $this.data('animations') !== null)
                settings.animations = $.isArray(settings.animations) ? settings.animations : settings.animations.split(' ')

            var options = $.extend({}, Dropdownhover.DEFAULTS, settings, typeof option == 'object' && option)

            if (!data) $this.data('bs.dropdownhover', (data = new Dropdownhover(this, options)))

        })
    }

    var old = $.fn.dropdownhover

    $.fn.dropdownhover = Plugin
    $.fn.dropdownhover.Constructor = Dropdownhover


    // DROPDOWNHOVER NO CONFLICT
    // ====================

    $.fn.dropdownhover.noConflict = function() {
        $.fn.dropdownhover = old
        return this
    }


    // APPLY TO STANDARD DROPDOWNHOVER ELEMENTS
    // ===================================

    var resizeTimer;
    $(document).ready(function() {
        if ($(window).width() >= 992) {

            // Breakpoin plugin is activated (768px)
            $('[data-hover="dropdown"]').each(function() {
                var $target = $(this)
                Plugin.call($target, $target.data())
            })
        }
    })
    $(window).on('resize', function() {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(function() {
            if ($(window).width() >= 992) // Breakpoin plugin is activated (768px)
                $('[data-hover="dropdown"]').each(function() {
                    var $target = $(this)
                    Plugin.call($target, $target.data())
                })
            else // Disabling and clearing plugin data if screen is less 768px
                $('[data-hover="dropdown"]').each(function() {
                    $(this).removeData('bs.dropdownhover')
                    if ($(this).hasClass('nav-link'))
                        $(this).parent('.dropdown').find('.dropdown').andSelf().off('mouseenter.bs.dropdownhover mouseleave.bs.dropdownhover')
                    else
                        $(this).find('.dropdown').off('mouseenter.bs.dropdownhover mouseleave.bs.dropdownhover')
                })
        }, 200)
    })

}(jQuery);
